﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace PathFinding
{

    static class GridUtil
    {
        // 方向：
        // 使用一个Byte存储方向角，顺时针从北方开始
        // 可能分别存储为8个位的掩码，也可以存储为数值
        // 作为集合时存储为掩码。
        // 北，东北，东，东南，南，西南，西，西北
        // N, NE, E, SE, S, SW, W, NW 
        // 0,  1,  2,   3,   4,   5,    6,   7
        const byte NO_DIRECTION = 8;

        /// <summary>
        /// 0-7的值存储八个方向
        /// 北，东北，东，东南，南，西南，西，西北
        /// </summary>
        public static byte DirectionOfMove(Vector2Int to, Vector2Int from)
        {
            if (from.x == to.x)
            {
                if (from.y == to.y)
                    return byte.MaxValue;
                else if (from.y < to.y)
                    return 4;
                else // from.y > to.y
                    return 0;
            }
            else if (from.x < to.x)
            {
                if (from.y == to.y)
                    return 2;
                else if (from.y < to.y)
                    return 3;
                else // from.y > to.y
                    return 1;
            }
            else
            { // from.x > to.x
                if (from.y == to.y)
                    return 6;
                else if (from.y < to.y)
                    return 5;
                else // from.y > to.y
                    return 7;
            }

        }

        public static bool directionIsDiagonal(byte dir)
        {
            return (dir % 2) != 0;
        }

        /// <summary>
        /// 获取某个坐标的8向邻接坐标点
        /// </summary>
        static Vector2Int adjustInDirection(Vector2Int c, int dir)
        {
            switch (dir)
            {
                case 0: c.y -= 1; return c;
                case 1: c.x += 1; c.y -= 1; return c;
                case 2: c.x += 1; return c;
                case 3: c.x += 1; c.y += 1; return c;
                case 4: c.y += 1; return c;
                case 5: c.x -= 1; c.y += 1; return c;
                case 6: c.x -= 1; return c;
                case 7: c.x -= 1; c.y -= 1; return c;
            }
            return new Vector2Int(-1, -1);
        }

        /// <summary>
        /// 一个节点的指定方向的邻接节点是否可进入
        /// </summary>
        static bool IsEnterable(in Vector2Int c, byte dirFrom, byte dir, in PFNode[,] nodes)
        {
            var coord = adjustInDirection(c, (dirFrom + dir) % 8);
            return !nodes[coord.x, coord.y].point.IsBlocked;
        }
    }
}
